\documentclass{article}
\usepackage{listings,geometry}
\geometry{margin=3cm}
\lstset{language=C++,columns=fixed,morekeywords={Scalar,Vector,Matrix,Domain,Set}}
\newcommand{\Tensors}{$\mathbf{T^3nsors}$}
\newcommand{\ura}{\mathbf}
\title{\Tensors\\v0.3.0}
\author{Mikbarr Studios}
\begin{document}

\maketitle
\tableofcontents

\section{What is \Tensors?}

\Tensors~ is a \lstinline'C++' framework for working with tensors numerically. Current techniques supported by the framework are constants and $n$-dimensional fields for scalars, vectors, and matrices (with higher-index tensor support planned), doing algebra with them, finding derivatives (including gradients, divergences, and curls), integration, and solving systems of partial differential equations. Much more is planned for the future.

The primary methodology behind \Tensors~ is that the code should look like math. Like any project of this sort, \Tensors~ is developed alongside a specific application, and features are added/fixed as the need arises. This framework came about as I would have to start some new project, particularly small ones, to test some system I was working with, and I'd have to reimplement many things (derivatives, array management, and equation solving are big ones) repeatedly. Even with copying and pasting, it was unnecessary work as I'd already written the code once, I should just reuse it. Even with I code reuse from project to project, much of what changes isn't math, it was just code that surrounds the math. I asked myself ``Why can't the code look like the math?'' and thus \Tensors~ was born.

\Tensors~ became a framework to share with others when I realized that there may be people out there doing similar kinds of work, who want to do numerical simulations, but don't want to worry about programming principles like pointers and the like. For example, suppose you have two vectors $A$ and $B$. Finding their sum $C = A+B$ is as simple as \lstinline'Vector C=A+B'. The dot product of the gradient of a scalar field $f$ and the curl of a vector field $A$ is \lstinline'diff(f)*curl(A)'.

\section{Terms of Use \& Licensing}

\subsection{Terms of Use}

The code is provided as-is in source form (though I intend to offer precompiled binaries in the future), with no guarantee that
\begin{itemize}
\item it'll compile
\item it'll run
\item you'll get help if you ask.
\end{itemize}
With that said,
\begin{itemize}
\item I try to only submit code to the repository that compiles without issue
\item I'm actively using the framework in an application, so if it doesn't run I'm having serious issues and will be trying to fix it
\item If you want help using the framework, I will try my best if I can to answer any questions and guide you.
\end{itemize}

\subsection{Licensing}

This is an area I find sticky. I'm hesitant to license anything under an existing open-source license, as it may bind me in the future or other inconveniences (for example, if I license anything under GPL, then anyone who used it would need to distribute a copy with their own software, etc.). For now, I'll try to cover all the usage cases.

\subsubsection{Everyone}

Sharing knowledge the framework is permitted and encouraged, though I ask that you share the website link rather than source code or binaries so that everybody can stay up to date.

\subsubsection{Students}

If you are an undergraduate or graduate student at a university in some scientific field, and want to use \Tensors~for a project that is personal (and won't be distributed) are free to use without permission. Any project that assists in research (not distributed but may be reviewed by colleages) or as part of a graded project (distributed only to grader or reviewer) are free to use without permission, though proper credit must be attributed to me (in the latter case to prevent suspicions of plagiarism).

\subsubsection{Other Academic}

If you are a student, professor, researcher, or other academic working not for profit and intend to use \Tensors~as part of a published paper, then you are free to use without permission, though proper credit must be attributed and I'd like to hear about the publication (if possible). Applications that aren't academic projects themselves, but are intended to be used in academic fields, are considered non-academic (for example, \Tensors~itself would be non-academic).

\subsubsection{Free applications}

If you'd like to use \Tensors~as part of a free\footnote{If your application has any of the following, it isn't free
\begin{itemize}
\item Costs the customer anything beyond charges to use the service or platform (App Store, Xbox Live Marketplace, and other digital stores are fine even if some cost to access)
\item Has ads for anything that's not other applications developed by you (ie, if you can make money from the ads, it's not free)
\item Is a demo
\item Bundled with or is dependent on hardware that you produce and/or sell
\end{itemize}} application, then you must ask permission (describing the app, how it's intended to be used, etc.), but will be provided for free.

\subsubsection{Non-free applications}

If you'd like to use \Tensors~as part of an application that is not free$^1$, please contact me and a price, if any, will be negotiated depending on the size and scope of the application.

\section{Platforms}

Currently I'm using exclusively \lstinline'C++' to write \Tensors~ and using nothing beyond the scope of the Standard Template Library (STL) (though if I include threading support, it will likely be using Boost). Any platform that supports STL will likely be compatible with \Tensors. I primarily develop for OS X, so included with the source is an Xcode project that compiles into a Framework, which you can drop into any Xcode project (including Objective-C/Cocoa projects) and use (it should also work for iOS, the Xcode project compiles to x86, x86\_64, ppc, ppc64, armv6, and armv7). However, my applications must run on Linux, so also included is a simple Makefile that will compile both static (\lstinline'.a') and dynamic (\lstinline'.so') libraries that you can link against (using \lstinline'gcc'). Though I have not tested, any other Unix flavour should also compile/run (so long as there's a C++ compiler with the STL, which should include BSD, Solaris, and others), and to my knowledge, I'm using nothing inherently incompatible with Windows.

\section{Features}

Now to the meat: what, exactly, can \Tensors do? I shall try to itemize them
\begin{itemize}
\item Work with tensors of up to two (currently) indices (that is, scalars, vectors, and matrices)
\item Work with tensor fields defined over a domain of any dimension of your choosing
\item Interact with tensors through addition, subtraction, multiplication, division, exponentiation, inner products, outer products, wedge products
\item Use various analytic functions on tensors such as trigonometry, norms, and logarithms.
\item Calculate the complete gradients of scalars and vectors.
\item Work with sets of scalars and vectors
\item Solve systems of partial differential equations
\end{itemize}

\subsection{Todo List}

These are features that will (hopefully) be implemented in the future
\begin{itemize}
\item Time support
\item Background metric support (up and down indices)
\item Threading support
\item Higher-index tensors (up to 5 indices would be nice to handle certain objects in general relativity)
\item Antiderivatives
\item File input/output
\end{itemize}

\subsection{Pipedreams}

These are features that I would love to figure out, but for now I've no idea how to do them
\begin{itemize}
\item Unlimited number of indices
\item Adaptive Mesh Refinement
\item Graphing package
\end{itemize}

\section{Operations}

Much of the tensor functionality is provided through the standard arithmetic operators ($+,-,*,/$) and all work exactly like you would imagine (since the whole point is to have code that looks like math, there's not much point in going through each individual function as it would merely be describing the math, which I assume any reader would already know). Adding or subtracting any two objects of the same type will return that type, with the result you would expect. Multiplying or dividing any type by a scalar or double will return that type with the result you would expect. There are functions of scalars, that also returns scalars, to compute the sine (\lstinline'sin(Scalar)'), sine squared (\lstinline'sin2(Scalar)'), cosine (\lstinline'cos(Scalar)'), square root (\lstinline'sqrt(Scalar)'), and base $b$ logarithm (\lstinline'log(Scalar,double)'), that all work like you would expect.

Also defined, but for other reasons needs special mention, is the caret ($\wedge$) operator. The operator has been overloaded to act as exponentiation, but because of operator precedence rules, using it without care will result in unexpected behaviour. In \lstinline'C++', $\wedge$ has precedence 11, below $*,/$ (5) and $+,-$ (6). That means that, while \lstinline'x^2' will be interpreted as $x^2$, if you have \lstinline'x*y^2', that will be interpreted as $(xy)^2$ (since $*$ has higher precedence than $\wedge$ and they both act left-to-right). As a more complicated example, \lstinline'x^2+y^2' would be interpreted as $\left(x^{2+y}\right)^2$; if you wanted $x^2+y^2$ then you would need to type \lstinline'(x^2)+(y^2)'.

There are two binary products between \lstinline'Vector's - dot and cross. The dot product, using the operator $*$, will return a \lstinline'Scalar'. The cross product will return another \lstinline'Vector', uses the operator $\%$, and assumes that the two vectors are three-dimensional (\lstinline'Vector(2)%Vector(2)' will abort the program). Matrices currently have no special operations defined.

\section{Getting started}

To use \Tensors, you must \lstinline'#include <T3nsors/T3nsors.h>' and link with \lstinline'-lT3nsors'. All classes are defined under the \lstinline'T3' namespace, so \lstinline'using namespace T3;' if often recommended as well (you can use this alongside the \lstinline'std' namespace, there shouldn't be any conflicts).

\subsection{Constants}

To use tensor constants, you declare new objects with only the dimension number (when applicable). Listing \ref{ex_constants} shows a simple case of declaring a new scalar $a$ and setting it equal to $3$. It then makes a new, $2$ dimensional vector $\ura x = \left(1,-2\right)$. It finally makes a new vector $\ura y = a \ura x$. Even though the dimensionality of $\ura y$ wasn't specified, it inherits from $\ura x$ as you would expect.

\begin{lstlisting}[caption=Example of tensor constants,label=ex_constants]
#include <T3nsors/T3nsors.h>
using namespace T3;

int main() {
	Scalar a = 3.;
	Vector x(2);
	x(0) = 1.;
	x(1) = -2.;
	Vector y = a*x;
	return 0;
}
\end{lstlisting}

\subsection{Fields}

To use tensor fields, you must use the \lstinline'Domain' class. \lstinline'Domain' is a special class (it is perhaps the most complex class in the entire package, as it's responsible for pretty much everything you would imagine a domain is responsible for), and you generally use one \lstinline'Domain' per project (constant objects have an internal, single-point instance of \lstinline'Domain', but you never have to worry about it's existence - you can combine constant and field objects naturally). You declare a \lstinline'Domain' by passing in the dimensionality of the domain, the number of points in the first direction, and the range\footnote{Due to limitations, be sure to pass \lstinline'double's only! \lstinline'3' and \lstinline'3.' are {\em not} the same thing. Most functions can dynamically cast \lstinline'int's to their numerically equivalent \lstinline'double's, but \lstinline'Domain' can't - it'll read the binary data as if it were a \lstinline'double' and will definitely create unexpected behaviour if you pass an \lstinline'int'.} of each dimension. The number of points in each other direction is chosen dynamically so that the grid spacing is the same in each dimension.

For example, if you want a 2-dimensional polar grid over $\left[0,1\right]\times\left[0,2\pi\right]$ with $10$ points in the $r$-direction, then you would declare \lstinline'Domain O(2, 10, 0., 1., 0., 2*M_PI);'. It'll actually create $11$ points in the $r$-direction, as it's designed to choose the zeroth point to correspond to $r=0$ while the tenth point corresponds to $r=1$, so that $\Delta r = \frac{1-0}{10} = 0.1$ as you would expect. It'll choose a number of points in the $\theta$ direction so $\Delta r = \Delta \theta = \Delta$. Since $\Delta\theta = \frac{2\pi}{N_\theta}$, $N_\theta = \lfloor\frac{2\pi}{\Delta}\rfloor = \lfloor\frac{2\pi}{0.1}\rfloor = \lfloor20\pi\rfloor = 62$.

\end{document}